#!/usr/bin/python
# -*- coding: utf-8 -*-

class Workspace_plotArea_cairo(object):
	""" Funktioniert nicht. """
	data = {
		'x_val' : [],
		'y_val' : [],
	}
	
	# Fenster-Parameter
	iWidth = 0
	iHeight = 0
	
	oWidget = None
	oNMR = None
	oCairo = None
	
	doPlot = False
	
	padding = 5
	x_axis_pos = 30
	spectra_space_bottom = 30
	spectra_space_top = 100
	
	x_axis_labels = 20
	x_axis_sublabels = 10 # Num of steps _with_ the start. 10 means there are 9 additional marks between two main labels
	
	cairoLinewidth = 1
	
	def __init__(self, widget, width, height):
		#super(Workspace_plotArea, self).__init__(widget.window, width, height)
		self.iWidth = width
		self.iHeight = height
		self.oWidget = widget
		
		self.oCairoOff = cairo.ImageSurface(cairo.FORMAT_ARGB32, 24, 24)
		self.oCairoOffC = cairo.Context(self.oCairoOff)
		
		# Weisse Fläche initialisieren
		self.oCairoOffC.set_source_rgb(0.5, 0.5, 0.5)
		self.oCairoOffC.rectangle(0, 0, self.iWidth, self.iHeight)
		self.oCairoOffC.fill()
		
	def setNMR(self, nmr):
		self.oNMR = nmr
		
	def setPlot(self, what):
		self.doPlot = what
		if what == True:
			self.plot()
			self.refresh()
		else:
			self.oCairoOff = cairo.ImageSurface(cairo.FORMAT_ARGB32, 24, 24)
			self.oCairoOffC = cairo.Context(self.oCairoOff)
			
			# Weisse Fläche initialisieren
			self.oCairoOffC.set_source_rgb(1.0, 1.0, 1.0)
			self.oCairoOffC.rectangle(0, 0, self.iWidth, self.iHeight)
			self.oCairoOffC.fill()
			
			self.refresh()
		
	def refresh(self, x = 0, y = 0, width = None, height = None):
		if width == None:
			width = self.iWidth
		
		if height == None:
			height = self.iHeight
			
		# Cairo initialisieren
		self.oCairo = self.oWidget.window.cairo_create()
		
		# Einstellungen
		self.oCairo.set_line_width(self.cairoLinewidth)
		
		self.oCairo.set_source_rgb(1.0, 1.0, 1.0)
		self.oCairo.rectangle(0, 0, self.iWidth, self.iHeight)
		self.oCairo.fill()
		
		if self.doPlot == True and isinstance(self.oNMR, nmr.nmr_prototype.NMR):
			#self.plot()
			print "Do Plot"
			self.oCairo.set_source_surface(self.oCairoOff)        
			self.oCairo.paint()
			#self.oCairo.set_source_surface (self.oCairoOff, 0, 0)
			#self.oCairo.rectangle(0, 0, 2000, 1000)
			#self.oCairo.fill()
		
		self.oCairo.rectangle(x, y, width, height)
		self.oCairo.clip()
		
	def clear(self):
		self.setPlot(False)
		self.data = {
			'x_val' : [],
			'y_val' : [],
		}
		self.oNMR = None
		
	def plot(self):
		values = self.oNMR.getValues()
		self.data['y_val'] = values[0]
		if len(values) == 2:
			self.data['x_val'] = values[1]
		else:
			self.data['x_val'] = range(0, len(self.data['x_val']))
			
		# Zeichne x-Achse
		self.drawXAxis()
			
		# Berechne die Maximal-Höhe für das Zeichnen
		self.spectraHeight = self.iHeight - 2*self.padding - self.x_axis_pos - self.spectra_space_bottom - self.spectra_space_top
		self.spectraWidth = self.iWidth - 2*self.padding
		
		if self.spectraHeight > 0:
			# Nur zeichnen, wenn überhaupt Platz vorhanden ist.
			# Suche Maximum und Minimum für y-Werte
			y_min = min(self.data['y_val'])[0]
			y_max = max(self.data['y_val'])[0]
			
			# Berechne Differenz
			y_dif = y_max - y_min
			
			# Das selbe für x:
			x_dif = len(self.data['y_val'])
			
			# Berechne das Mapping Pixel => y
			self.zoom_y = float(self.spectraHeight) / y_dif
			self.zoom_x = float(self.spectraWidth) / x_dif
			
			# Zeichne Plot
			self.drawPlot()
			self.flagXAxis()
		
	def drawXAxis(self):
		# Zeichnet die Achsen-Linie
		self.oCairoOffC.set_source_rgb(0.0, 0.0, 0.0)
		self.oCairoOffC.move_to(self.x(0), self.y(self.x_axis_pos))
		self.oCairoOffC.line_to(self.x(0, True), self.y(self.x_axis_pos))
		self.oCairoOffC.stroke()
		
	def flagXAxis(self):
		specWidth = self.oNMR.getSpectralWidth()
		specLeftPPM = self.oNMR.getOffset()
		specRightPPM = specLeftPPM - specWidth
		resolution = len(self.data['y_val']) / specWidth
		diffPPM = specWidth - specLeftPPM
		
		if specWidth / self.x_axis_labels < 1:
			steps = math.floor(specWidth)
		else:
			steps = math.floor(specWidth / self.x_axis_labels)
		
		specLeftPPMMark = math.ceil(specLeftPPM) if specLeftPPM < 0 else math.floor(specLeftPPM)
		specRightPPMMark = math.ceil(specRightPPM) if specRightPPM < 0 else math.floor(specRightPPM)
		
		for i in range(int(specLeftPPMMark), int(specRightPPMMark), int(-1*steps)):
			x = ((i + diffPPM) * resolution) * self.zoom_x
			
			self.oCairoOffC.set_source_rgb(0.0, 0.0, 0.0)
			self.oCairoOffC.move_to(self.x(x), self.y(self.x_axis_pos))
			self.oCairoOffC.line_to(self.x(x), self.y(self.x_axis_pos - 8))
			self.oCairoOffC.stroke()
		
		
	def drawPlot(self):
		# Lege mit dem Polygon los.
		points = []
		# Schwarzer Strich
		self.oCairoOffC.set_source_rgb(0.0, 0.0, 0.0)
		# Startpunkt setzen
		self.oCairoOffC.move_to(self.x(0), self.y(self.x_axis_pos + self.spectra_space_bottom))
		
		x = 0
		for y in self.data['y_val']:
			x += 1
			# Appendiere x und y
			if isinstance(y, tuple):
				y = y[0]
			#coords = (int(self.x(x * self.zoom_x)), int(self.y(y * self.zoom_y + self.x_axis_pos + self.spectra_space_bottom)))
			#points.append(coords)
			self.oCairoOffC.line_to(self.x(x * self.zoom_x), self.y(y * self.zoom_y + self.x_axis_pos + self.spectra_space_bottom))
			
		# Zeichnen!
		self.oCairoOffC.stroke()
			
		#a = self.draw_lines(self.oWidget.get_style().black_gc, points)
			
	def x(self, x, reversed = False):
		if reversed:
			return self.iWidth - (x + self.padding)
			#return int(round(self.iWidth - (x + self.padding)))
		else:
			return x + self.padding
			#return int(round(x + self.padding))
		
	def y(self, y, reversed = False):
		if reversed:
			return y + self.padding
			#return int(round(y + self.padding))
		else:
			return self.iHeight - (y + self.padding)
			#return int(round(self.iHeight - (y + self.padding)))

